This is an inconsistent synchronization.
Private field lastUsed in org.apache.commons.dbcp.AbandonedTrace class could be accessed by multiple threads, but it is not proper protected.More details about this bug are at DBCP-271 JIRA page.
Write Thread: for (long i = 0; i < SIZE; i++) {
1 test.setLastUsed(i);
}
Read Thread: while (true)
{
2 value = test.getLastUsed();
3 if (value == SIZE - 1) {
break;
}
}
a) Write Thread modifies lastUsed value at 1.
b) Read Thread reads lastUsed value at 2.
c) Read Thread checks if lastUsed
value reaches a certain value. If not, keeps looping and checking.
There are two possible results of step c, depending on machine's CPU
model and operation system and other factors:
1) test.getLastUsed() never gets the latest value modified in Write
Thread, so it's an infinite loop.
2) test.getLastUsed() gets
the latest value modified in Write Thread, but not timely. It loops
more times than when lastUsed is properly synchronized.
This bug is reproduced under dbcp 1.2 and JDK 1.6_33.
Execute the
following scripts to run the test to reproduce the bug (assume the location of the dbcp test project is dbcp_test_home).
Warning:
This reproduction has chances to go into an infinite loop.